<template>
  <view class="base-tree">
    <view class="base-tree__item" v-for="item in state.treeData" :key="item.id" @click.stop="handleSelect(item)">
      <view class="base-tree__item--label">
        <IconFont
          v-if="item.children?.length"
          :name="item.isOpen ? 'rect-down' : 'rect-right'"
          size="10"
          color="#444"
        ></IconFont>
        <view v-else style="width: 10px; height: 40px"></view>
        <text class="label-name">{{ item[props.defaultProps.label] }}</text>
      </view>

      <view class="base-tree__item--children" v-if="item.isOpen && item.children?.length">
        <BaseTree :treeData="item.children" :defaultProps="props.defaultProps" @select="handleSelect" />
      </view>
    </view>
  </view>
</template>

<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "BaseTree",
});
</script>

<script setup>
import { reactive, watch } from "vue";
import BaseTree from "./index.vue";

const emits = defineEmits(["select"]);

const props = defineProps({
  treeData: {
    type: Array,
    default: () => [],
  },
  modelValue: {
    type: [Array, String],
    default: "",
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  defaultProps: {
    type: Object,
    default: () => ({
      label: "label",
      value: "value",
    }),
  },
});

const state = reactive({
  treeData: [],
  selected: null,
});

watch(
  () => props.treeData,
  () => {
    state.treeData = props.treeData.map((item) => ({
      ...item,
      isOpen: false,
    }));
  },
  {
    immediate: true,
  }
);

const handleSelect = (treeItem) => {
  if (treeItem.children?.length) {
    treeItem.isOpen = !treeItem.isOpen;
  } else {
    state.selected = props.multiple ? [...state.selected, treeItem] : treeItem;
    emits("select", state.selected);
  }
};
</script>

<style lang="scss">
.base-tree {
  // 样式定义
  width: 100vw;
  background: #fff;

  &__item {
    line-height: 36px;
    // border-top: 1px solid #f5f5f5;
    color: #333;
    font-size: 14px;

    &.selected {
      background: #f8f8f9;
      color: #4c7bfd;
    }

    &--label {
      display: flex;
      align-items: center;

      .label-name {
        margin-left: 4px;
      }
    }

    &--children {
      padding-left: 16px;
    }
  }
}
</style>
